/*
 * The Client
 */
package gui;

import Protocol.PacketFactory;
import Protocol.PacketTypeKeeper;
import Protocol.QueryRequestPacket;
import Protocol.QueryResponsePacket;
import handler.PanelController;
import handler.ClientHandler;
import client.Startup;
import config.Config;
import config.Content;
import handler.TabbedPaneListener;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;

/**
 * Bunie Client
 * @author Kay van Bree, Joep Kemperman
 * @version 0.4
 */
public class Client extends JFrame {	
	public JMenuBar menu;
	public JMenu menuFile, menuView;
	public JMenuItem itemExit, itemSettings, itemLogout;
	public JCheckBoxMenuItem itemShowLog;
	public JPanel buttonPanel, infoPanel;
	public ButtonGroup viewButtonGroup;
	public JRadioButtonMenuItem itemTableView, itemBarGraphView, itemPieChartView;
	protected JTabbedPane tabbedPane;
	protected JPanel contentPanel;
	protected JPanel welcomePanel;
	private JPanel menuPanel;
	private final JLabel creditsLabel;
	private final JPanel creditsPanel;
	private QueryButtonPanel queryButtonPanel;
	protected ClientHandler clientHandler;
	protected PanelController panelController;
	protected JScrollPane tableScrollPane;
	protected TablePanel tablePanel;
	protected BarGraphPanel barGraphPanel;
	protected PieChartPanel pieChartPanel;
	
	/**
	 * Creates a GUI and builds up the parts that Master and Info have in common
	 * Sets up a connection.
	 * 
	 * @author Kay van Bree, Joep Kemperman
	 * @since 0.1
	 * @param framename The name of the frame
	 */
	public Client(String framename){
		super(framename);
		Content.log.println("Loading client...");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(1024, 600);
		setLocationByPlatform(true);
		setLayout(new BorderLayout());
		
		clientHandler = new ClientHandler(this);
		
		barGraphPanel = new BarGraphPanel();
		pieChartPanel = new PieChartPanel();
		
		// Create the tabbedPane
		tabbedPane = new JTabbedPane();
		tabbedPane.setUI(new CustomTabbedPaneUI());
		
		// Create and set main content
		welcomePanel = new JPanel();
		welcomePanel.add(new JLabel("Welcome panel"));
		tablePanel = new TablePanel();
		tableScrollPane = new JScrollPane(tablePanel);
		tableScrollPane.getVerticalScrollBar().setUnitIncrement(10);
		tableScrollPane.getHorizontalScrollBar().setUnitIncrement(6);
		tabbedPane.addTab("Welcome panel", welcomePanel);
		tabbedPane.addTab("Table panel", tableScrollPane);
		tabbedPane.addTab("Bar graph", barGraphPanel);
		tabbedPane.addTab("Pie Chart", pieChartPanel);
		
		panelController = new PanelController(tablePanel, tableScrollPane, barGraphPanel, pieChartPanel);
		queryButtonPanel = new QueryButtonPanel(panelController);
		setMenuPanel(queryButtonPanel);
		this.setResizable(false);
		setContentPanel(tabbedPane);
		
		setJMenuBar(getMenu());
		add(menuPanel, BorderLayout.WEST);
		add(contentPanel, BorderLayout.CENTER);
		
		// Create the bottom label
		creditsLabel = new JLabel("Software designed by ISM2Ia - DSW");
		creditsPanel = new JPanel();
		creditsPanel.add(creditsLabel);
		add(creditsLabel, BorderLayout.SOUTH);
		
		setIcons();
	}
	
	/**
	 * What to do while running
	 * @author Kay van Bree
	 * @since 0.3
	 */
	public void run(){
		Content.log.println("Run client, run!");
		Startup.login.setVisible(false);
		Startup.login = null;
		setVisible(true);
		queryButtonPanel.populate();
		Config.queryStatus = getQueryStatus();
		new Thread(new QueryThreat()).start();
	}
	
	/**
	 * Getter for the current query status in the database
	 * @return Query status
	 */
	private String getQueryStatus() {
		QueryRequestPacket request = 
			(QueryRequestPacket) PacketFactory.getPacket(PacketTypeKeeper.QUERYREQUESTPACKET);
		QueryResponsePacket response = null;
		request.setQuery("SELECT * FROM [QueryChange];");
		request.setStatus(QueryRequestPacket.SELECT);
		try {
			response = (QueryResponsePacket) Content.connection.communicate(request);
		} catch (Exception ex) {
			Content.log.println("Couldn't receive query edited status");
		}
		ArrayList<String[]> list = response.getListWithAccounts();
		return list.get(0)[0];
	}
	
	/**
	 * This builds up the menubar
	 * @author Kay van Bree
	 * @since 0.2
	 */
	private JMenuBar getMenu(){
		menu = new JMenuBar();
		
		// FILE
		menuFile = new JMenu("File");
		menu.add(menuFile);
		
		itemSettings = new JMenuItem("Settings");
		itemSettings.addActionListener(clientHandler);
		menuFile.add(itemSettings);
		menuFile.addSeparator();
		itemLogout = new JMenuItem("Logout");
		itemLogout.addActionListener(clientHandler);
		menuFile.add(itemLogout);
		itemExit = new JMenuItem("Exit");
		itemExit.addActionListener(clientHandler);
		menuFile.add(itemExit);
		
		// VIEW
		menuView = new JMenu("View");
		menu.add(menuView);
		
		itemShowLog = Content.log.getMenuItem();
		itemShowLog.addItemListener(clientHandler);
		menuView.add(itemShowLog);
		
		return menu;
	}
	
	/*
	 * Set the icons
	 * @author Kay van Bree
	 */
	public void setIcons(){
		ArrayList imageList = new ArrayList();
		imageList.add(Toolkit.getDefaultToolkit().getImage("bunie50x50.png"));
		setIconImages(imageList);
	}
	
	/**
	 * Sets the menu Panel
	 * @author Kay van Bree
	 * @param panel 
	 */
	private void setMenuPanel(JPanel panel){
		menuPanel = new JPanel();
		menuPanel.setPreferredSize(new Dimension(250, 200));
		menuPanel.add(panel);
	}
	
	/**
	 * Returns the current menu Panel
	 * @author Kay van Bree
	 * @return 
	 */
	private JPanel getMenuPanel() {
		return menuPanel;
	}
	
	/**
	 * Resets the content panel and adds what you want
	 * @author Kay van Bree
	 * @param panel 
	 */
	private void setContentPanel(JTabbedPane jtp){
		contentPanel = new JPanel(new BorderLayout());
		contentPanel.add(jtp);
	}
	
	/**
	 * Return the current content panel
	 * @author Kay van Bree
	 * @return 
	 */
	private JPanel getContentPanel(){
		return contentPanel;
	}
	
	/**
	 * Runnable that checks if any queries have been updated.
	 * If so, client will reload queries.
	 * @author Joep Kemperman
	 */
	class QueryThreat implements Runnable {

		@Override
		public void run() {
			QueryRequestPacket request;
			QueryResponsePacket response = null;
			ArrayList<String[]> list;
			String queryStatus;
			while (true) {
				request = 
					(QueryRequestPacket) PacketFactory.getPacket(PacketTypeKeeper.QUERYREQUESTPACKET);
				request.setQuery("SELECT * FROM [QueryChange];");
				request.setStatus(QueryRequestPacket.SELECT);
				try {
					response = (QueryResponsePacket) Content.connection.communicate(request);
				} catch (Exception ex) {
					Content.log.println("Couldn't receive query edited status");
				}
				list = response.getListWithAccounts();
				queryStatus = list.get(0)[0];
				if (!Config.queryStatus.equals(queryStatus)) {
					Config.queryStatus = queryStatus;
					reloadQueries();
				} else
					Content.log.println("No new queries!");
				try {
					Thread.sleep(10000);
				} catch (InterruptedException ex) {
					Content.log.println("Could not sleep. (QueryThreat)");
				}
			}
		}

		/**
		 * Reloads all queries.
		 */
		private void reloadQueries() {
			queryButtonPanel.reset();
			Content.log.println("Reloaded queries!");
		}
	}
}
